// The Swift Programming Language
// https://docs.swift.org/swift-book
import UIKit
import Starscream
import RouterService
import HUD
import Log
import ConstantModule

extension FiveoSocket: FiveoSocketProtocol {
    func setsyStem_prompt_Scene(system_prompt: String) {
        self.socket.setsyStem_prompt_Scene(system_prompt: system_prompt)
    }
    func sceneChangeNoDisconnect(type: SceneType, sceneChangeFinashBlock: ((Bool) -> Void)?) {
        sceneType = type
        // 设置开场白
        self.socket.setsyStem_prompt_Scene(system_prompt: type.system_prompt)
        // 设置开场白
        let tmp = type.prologue.components(separatedBy: "</style>").last ?? ""
        MHLog.log("设置开场白:\(tmp)")
        self.socket.PostSayIt(text: tmp)
        sceneChangeFinashBlock?(true)
    }
    func sceneChange(type: SceneType, sceneChangeFinashBlock: ((Bool) -> Void)?) {
        sceneType = type
        // 重新链接
        connect { success in
            if !success {
                return
            }
            if type == .None { // 不设置开场白
                sceneChangeFinashBlock?(success)
                return
            }
            self.socket.setsyStem_prompt_Scene(system_prompt: type.system_prompt)
            // 设置开场白
            let tmp = type.prologue.components(separatedBy: "</style>").last ?? ""
            print("设置开场白:\(tmp)")
            self.socket.PostSayIt(text: tmp)
            sceneChangeFinashBlock?(true)
        }
        
    }
    
    func setDefultSetsyStem_prompt_voice() {
        self.socket.setDefultSetsyStem_prompt_Voice()
    }
    func swichvoiceType(voiceType: String,
                        system_promat: String,
                        completion: ((Bool) -> Void)?){
        let patams = self.socket.params
        patams.voice_type = voiceType
        patams.system_prompt_custom_subttile = system_promat
        completion?(true)
//        self.socket.startConnect(params: patams, connnectCompletion: completion)
    }
//      切换数学解题一对一音色：如果前置音色是女生，则进入到数学场景就指定为：甜美小源；如果是男生，则指定温暖阿虎
//    - 音色为 F12或 女国59时 -> 甜美小源
//    - 其他 -> 温暖阿虎
    func math_swichvoiceType(completion: ((Bool) -> Void)?){
        let patams = self.socket.params
        if  TTSType.ttsype(ttsype: patams.voice_type).gender == .man {
            patams.voice_type = TTSType.ahu.voiceType
            patams.system_prompt_custom_subttile = TTSType.ahu.system_promat
        }else{
            patams.voice_type = TTSType.sweet.voiceType
            patams.system_prompt_custom_subttile = TTSType.sweet.system_promat
        }
        self.socket.startConnect(params: patams, connnectCompletion: completion)
    }
    func defulatPostSayIt() {
        // 设置开场白
        let voiceType = App.VoiceType.share.current
        self.socket.PostSayIt(text: "")
    }
    func PostSayIt(text: String) {
        socket.PostSayIt(text: text)
    }
    func wirteMultimodalGenerate(text: String, images: [String]?, audio: [String]?,
                                 completion: ((_ success: Bool) -> ())?) {
        MHLog.log("wirteMultimodalGenerate:\(text)")
        socket.wirteMultimodalGenerate(text: text, images: images, audio: audio, completion: completion)
    }
    
    func connect(connnectBlock: ((Bool) -> Void)?) {
        self.connnectBlock = connnectBlock
        let params = WebSocketParams.defult
        params.voice_type = App.VoiceType.share.current.name
        params.system_prompt_custom_subttile = App.VoiceType.share.current.name

        socket.startConnect(params: params) { [weak self] success in
            if !success {
                MHLog.log(("链接失败，请检查网络"))
                self?.connnectBlock?(false)
            }
        }
    }
    func close(closeBlock: ((Bool) -> Void)?) {
        self.close(destroy: true, closeBlock: closeBlock)
    }
    func close(destroy:Bool, closeBlock: ((Bool) -> Void)?) {
        self.rtc.stopPreview()
        self.rtc.stopAudio()
        self.rtc.leaveChannel { [weak self] in
            self?.socket.disconnect(disconnnectCompletion: { success in
                closeBlock?(success)
            })
            if destroy {
                self?.rtc.destroy()
            }
        }
    }
    
    func leaveChannel() {
        rtc.stopPreview()
        rtc.leaveChannel(block: nil)
        rtc.destroy()
    }
    
    func startVideo(localView: UIView) {
        videoflag = true
        rtc.startPreview(localView: localView)
        
        if socket.isOnlyAudio { // 从纯语音切换到视频
            socket.isOnlyAudio = false
            connect(connnectBlock: nil)
            return
        }
        if !socket.isOnlyAudio { // 视频关x闭切换到视频打开
            socket.isOnlyAudio = false
            self.rtc.startPreview(localView: localView)
            return
        }
    }
    
    func stopVideo() {
        videoflag = false
        if  !socket.isOnlyAudio { // 视频打开切换到关闭视频
            //            socket.isOnlyAudio = true
            self.rtc.stopPreview()
            return
        }
    }
    
    func flipCamera() {
        rtc.switchCamera()
    }
    func muteLocalAudioStream(enable: Bool) {
        if enable {
            audioFlag = false
            rtc.disRecording()
        }else{
            audioFlag = true
            rtc.startAudio()
        }
    }
    func enableLocalAudio(enable: Bool) {
        if enable {
            audioFlag = true
            rtc.startAudio()
        }else{
            audioFlag = false
            rtc.stopAudio()
            
        }
    }
    
    func setCameraFocusPositionInPreview(positionX: CGFloat, positionY: CGFloat) {
        let point = CGPoint(x: positionX, y: positionY)
        rtc.setCameraFocusPositionInPreview(point: point)
    }
    
    func setCameraTorchOn(on: Bool) {
        rtc.setCameraTorchOn(on: on)
    }
}
class FiveoSocket {
    static let share = FiveoSocket()
    private var videoflag = false
    private var audioFlag = false
    weak var delegate: FiveoSocketDelegate?
    private var sceneChangeFinashBlock: ((Bool) -> Void)?
    private var isMute = false
    var sceneType: SceneType = .None
    private var connnectBlock: ((Bool) -> Void)?
    private lazy var socket: FiveoWebSocket = {
        let v = FiveoWebSocket.share
        v.delegate = self
        return v
    }()
    private lazy var rtc: RtcManager = {
        let v = RtcManager.share
        v.delegate = self
        return v
    }()
    var isConnect: Bool {
        return socket.isConnected
    }
}

extension FiveoSocket: FiveoWebSocketDelegate {
    
    func webSocket(speakstatus: FiveoSpeakStatus, params: [String : Any]?) {
        delegate?.webSocket(speakstatus: speakstatus, params: params)
        switch speakstatus {
        case .StartSpeaking: // 展示app说话中
            break
        case .StopSpeaking:// 展示模型思考中
            break
        case .AudioAccepting:
            MHLog.log("链接成功")
        case .VideoAccepting:
            if !videoflag {
                rtc.stopPreview()
            }
            if !audioFlag {
                rtc.disRecording()
            }
            socket.setDefultSetsyStem_prompt_Voice()
            connnectBlock?(true)
            connnectBlock = nil
        case .None:
            break
        default:
            break
        }
        
    }
    
    func webSocket(error: (any Error)?) {
        delegate?.webSocket(error: error)
    }
    
    func webSocket(agoraComplation: AgoraModel, audioOnly: Bool) {
        
        rtc.sharedEngine(withAppId: agoraComplation.agora_appid)
        rtc.leaveChannel { [weak self] in
            guard let self = self else { return }
            self.rtc.joinChannelByTokenAudio(byToken: agoraComplation.agora_token, channelId: agoraComplation.agora_channel_id, uid: agoraComplation.client_uid.int ?? 1, cameraTrack: !audioOnly)
            if self.isMute {
                self.rtc.stopAudio()
            }else{
                self.rtc.startAudio()
            }
        }
    }
    
    func webSocket(allEvent: Starscream.WebSocketEvent) {
        
    }
    func webSocket(event: WebSocketReceiveType, params: [String : Any]?) {
        
    }
    
    
}
extension FiveoSocket: RtcProtocol {
    func rtcEngine(uid: Int, isSpeaking: Bool, totalVolume: Int) {
        delegate?.webSocketRtcEngine(uid: uid, isSpeaking: isSpeaking, totalVolume: totalVolume)
    }
    
}

